home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; The data in this file contains enhancments. ;;;;;
- ;;; ;;;;;
- ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
- ;;; All rights reserved ;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; (c) Copyright 1980 Massachusetts Institute of Technology ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (in-package "MAXIMA")
- (macsyma-module linnew)
-
- ;; This is a matrix package which uses minors, basically.
- ;; TMLINSOLVE(LIST-OF-EQUAIONS,LIST-OF-VARIABLES,LIST-OF-VARIABLES-TO-BE-OBTAINED)
- ;; solves the linear equation. LIST-OF-VARIABLES-TO-BE-OBTAINED can be omitted,
- ;; in which case all variables are obtained. TMNEWDET(MATRIX,DIMENSION)
- ;; computes the determinant. DIMENSION can be omitted. The default is
- ;; DIMENSION=(declared dimension of MATRIX). TMINVERSE(MATRIX) computes the
- ;; inverse of matrix.
-
- ;; The program uses hash arrays to remember the minors if N > threshold. If
- ;; $WISE is set to T, the program knocks out unnecessary elements. But also it
- ;; kills necessary ones in the case of zero elements! The $WISE flag should
- ;; not be set to T for inverse. The default of $WISE is NIL.
-
- ;; There seem to have been a number of bugs in this code. I changed
- ;; the array referencing to value cell, and some of the stuff about
- ;; cre form. It now seems tminverse and tmlinsolve, now seem to work. --wfs.
-
- ;;these are arrays
- (DECLARE-TOP(special *TMARRAYS* *A2* *B* *AA*
- *ROW* *COL* *ROWINV* *COLINV* *INDX* ))
-
- (DECLARE-TOP(SPECIAL N NX IX))
-
- (DECLARE-TOP(SPECIAL $LINENUM $DISPFLAG $LINECHAR $WISE $FOOL))
-
- (defvar *tmarrays* nil)
-
- ;; If N < threshold declared array is used, otherwise hashed array.
-
-
- (DEFMACRO THRESHOLD () 10.)
-
- (DEFUN TMINITIALFLAG NIL
- (COND ((NOT (BOUNDP '$WISE)) (SETQ $WISE NIL)))
- (COND ((NOT (BOUNDP '$FOOL)) (SETQ $FOOL NIL))))
-
- ;; TMDET returns the determinant of N*N matrix A2 which is in an globally
- ;; declared array A2.
-
- (DEFUN TMDET (A4 N)
- (PROG (INDEX RESULT IX)
- (TMINITIALFLAG)
- (TMHEADING)
- (SETQ IX 0. NX 0.)
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (SETQ INDEX (CONS I INDEX)))
- (SETQ INDEX ;(REVERSE INDEX)
- (nreverse index))
- (SETQ RESULT (TMINOR A4 N 1. INDEX 0.))
- (RETURN RESULT)))
-
- ;; TMLIN SOLVES M SETS OF LINEAR EQUATIONS WHITH N UNKNOWN VARIABLES. IT SOLVES
- ;; ONLY FOR THE FIRST NX UNKNOWNS OUT OF N. THE EQUATIONS ARE EXPRESSED IN
- ;; MATRIX FORM WHICH IS IN N*(N+M) ARRAY A2. AS USUAL , THE LEFT HAND SIDE N*N
- ;; OF A2 REPRESENTS THE COEFFICIENT MATRIX, AND NEXT N*M OF A2 IS THE RIGHT
- ;; HAND SIDE OF THE M SETS OF EQUATIONS. SUPPOSE N=3, M=2, AND THE UNKKNOWNS
- ;; ARE (X1 Y1 Z1) FOR THE FIRST SET AND (X2 Y2 Z2) FOR THE SECOND. THEN THE
- ;; RESULT OF TMLIN IS ((DET) (U1 U2) (V1 V2) (W1 W2)) WHERE DET IS THE
- ;; DETERMINANT OF THE COEFFICIENT MATRIX AND X1=U1/DET, X2=U2/DET, Y1=V1/DET,
- ;; Y2=V2/DET ETC.
-
- (DEFUN TMLIN (A4 N M NX)
- (PROG (INDEX R)
- (TMDEFARRAY N)
- (TMINITIALFLAG)
- (TMHEADING)
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (SETQ INDEX (CONS I INDEX)))
- (SETQ INDEX (REVERSE INDEX))
- (SETQ R
- (DO ((IX 0. (f1+ IX)) (RESULT))
- ((> IX NX) (REVERSE RESULT))
- (SETQ RESULT
- (CONS (DO ((I 1. (f1+ I)) (RES))
- ((> I
- (COND ((= IX 0.) 1.)
- (T M)))
- (REVERSE RES))
- (COND ((NOT $WISE)
- (TMKILLARRAY IX)))
- (SETQ RES
- (CONS (TMINOR A4
- N
- 1.
- INDEX
- I)
- RES)))
- RESULT))
- (COND ((AND (= IX 0.)
- (EQUAL (CAR RESULT)
- '(0. . 1.)))
- (merror "COEFFICIENT MATRIX IS SINGULAR")))))
- (TMREARRAY N)
- (RETURN R)))
-
- ;; TMINOR ACTUALLY COMPUTES THE MINOR DETERMINANT OF A SUBMATRIX OF A2, WHICH
- ;; IS CONSTRUCTED BY EXTRACTING ROWS (K,K+1,K+2,...,N) AND COLUMNS SPECIFIED BY
- ;; INDEX. N IS THE DIMENSION OF THE ORIGINAL MATRIX A2. WHEN TMINOR IS USED
- ;; FOR LINEAR EQUATION PROGRAM, JRIGHT SPECIFIES A COLUMN OF THE CONSTANT
- ;; MATRIX WHICH IS PLUGED INTO AN IX-TH COLUMN OF THE COEFFICIENT MATRIX FOR
- ;; ABTAINING IX-TH UNKNOWN. IN OTHER WORDS, JRIGHT SPECIFIES JRIGHT-TH
- ;; EQUATION.
-
-
- (DEFUN TMINOR (A4 N K INDEX JRIGHT)
- (PROG (SUBINDX L RESULT NAME AORB)
- (setq a4 (get-array-pointer a4))
- (COND
- ((= K N)
- (SETQ RESULT
- (COND ((= K IX) (AREF A4 (CAR INDEX) (f+ JRIGHT N)))
- (T (AREF A4 (CAR INDEX) K)))))
- (T
- (DO
- ((J 1. (f1+ J)) (SUM '(0. . 1.)))
- ((> J (f1+ (f- N K))) (SETQ RESULT SUM))
- (SETQ L (EXTRACT INDEX J))
- (SETQ SUBINDX (CADR L))
- (SETQ L (CAR L))
- (SETQ AORB (COND ((= K IX) (AREF A4 L (f+ JRIGHT N)))
- (T (AREF A4 L K))))
- (COND
- ((NOT (EQUAL AORB '(0. . 1.)))
- (SETQ NAME (TMACCESS SUBINDX))
- (SETQ
- SUM
- (funcall (COND ((ODDP J) 'RATPLUS)
- (T 'RATDIFFERENCE))
- SUM
- (RATTIMES
- AORB
- (COND ($FOOL (TMINOR A4 N (f1+ K) SUBINDX JRIGHT))
- (T (COND ((NOT (NULL (TMEVAL NAME)))
- (TMEVAL NAME))
- ((TMNOMOREUSE J L K)
- (TMSTORE NAME NIL)
- (TMINOR A4
- N
- (f1+ K)
- SUBINDX
- JRIGHT))
- (T (TMSTORE NAME
- (TMINOR A4
- N
- (f1+ K)
- SUBINDX
- JRIGHT))))))
- T)))))
- (COND ($WISE (COND ((TMNOMOREUSE J L K)
- (TMKILL SUBINDX K))))))))
- (RETURN RESULT)))
-
- (DEFUN EXTRACT (INDEX J)
- (DO ((IND INDEX (CDR IND)) (COUNT 1. (f1+ COUNT)) (SUBINDX))
- ((NULL IND))
- (COND ((= COUNT J)
- (RETURN (LIST (CAR IND) (NCONC SUBINDX (CDR IND)))))
- (T (SETQ SUBINDX (NCONC SUBINDX (LIST (CAR IND))))))))
-
- (DECLARE-TOP(SPECIAL VLIST VARLIST GENVAR))
-
-
- (DEFUN TMRATCONV (BBB N M)
- (PROG (CCC)
- (declare (special ccc)) ;Tell me this worked in Maclisp. --gsb
- ;Actually, i suspect it didn't, at least ever since
- ; (sstatus punt).
- (SET 'CCC BBB)
- (DO ((K 1. (f1+ K)))
- ((> K N))
- (DO ((J 1. (f1+ J)))
- ((> J M))
- (NEWVAR1 (STORE (aref *A2* K J)
- (maref ccc k j)
- ;; (nth j (nth k *a2*))
- ;; (MEVAL (LIST (LIST 'CCC 'array) K J)) ;;just the
- ))))
-
- (NEWVAR (CONS '(MTIMES) VLIST))
- (DO ((K 1. (f1+ K)))
- ((> K N))
- (DO ((J 1. (f1+ J)))
- ((> J M))
- (STORE (aref *A2* K J)
- (CDR (RATREP* (aref *A2* K J))))))))
-
- (DEFMFUN $TMNEWDET N
- (PROG (*AA* R VLIST)
- (COND ((= N 2.)
- (COND ((NOT (INTEGERP (SETQ N (ARG 2.))))
- (merror "WRONG ARG")))
- (SETQ *AA* (ARG 1.)))
- ((AND (= N 1.) ($MATRIXP (SETQ *AA* (ARG 1.))))
- (SETQ N (LENGTH (CDR (ARG 1.)))))
- (T (merror "WRONG ARG")))
- (setq *A2* (*ARRAY nil 'T (f1+ N) (f1+ N)))
- (TMDEFARRAY N)
- (TMRATCONV *AA* N N)
- (SETQ R (CONS (LIST 'MRAT
- 'SIMP
- VARLIST
- GENVAR)
- (TMDET '*A2* N)))
- (*TMREARRAY '*A2*)
- (TMREARRAY N)
- (RETURN R)))
-
- (DEFMFUN $TMLINSOLVE NARG (TMLINSOLVE (LISTIFY NARG)))
-
- (DEFUN TMLINSOLVE (ARGLIST)
- (PROG (EQUATIONS VARS OUTVARS RESULT *AA*)
- (SETQ EQUATIONS (CDAR ARGLIST)
- VARS (CDADR ARGLIST)
- OUTVARS (COND ((NULL (CDDR ARGLIST)) VARS)
- (T (CDADDR ARGLIST)))
- ARGLIST NIL)
- (SETQ VARS (TMERGE VARS OUTVARS))
- (SETQ NX (LENGTH OUTVARS))
- (SETQ N (LENGTH VARS))
- (COND ((NOT (= N (LENGTH EQUATIONS)))
- (RETURN (PRINT 'TOO-FEW-OR-MUCH-EQUATIONS))))
- (SETQ
- *AA*
- (CONS
- '($MATRIX SIMP)
- (MAPCAR
- #'(LAMBDA (EXP)
- (APPEND
- '((MLIST))
- (MAPCAR #'(LAMBDA (V)
- (PROG (R)
- (SETQ EXP
- ($BOTHCOEF EXP V)
- R
- (CADR EXP)
- EXP
- (MEVAL (CADDR EXP)))
- (RETURN R)))
- VARS)
- (LIST (LIST '(MMINUS) EXP))))
- (MAPCAR #'(LAMBDA (E) (MEVAL (LIST '(MPLUS)
- ($LHS E)
- (LIST '(MMINUS)
- ($RHS E)))))
- EQUATIONS))))
- (SETQ RESULT (CDR ($TMLIN *AA* N 1. NX)))
- (RETURN
- (DO
- ((VARS (CONS NIL OUTVARS) (CDR VARS))
- (LABELS)
- (DLABEL)
- (NAME))
- ((NULL VARS)
- (CONS '(MLIST) (CDR (REVERSE LABELS))))
- (SETQ NAME (MAKELABEL $LINECHAR))
- (SETQ $LINENUM (f1+ $LINENUM))
- (SET NAME
- (COND ((NULL (CAR VARS))
- (SETQ DLABEL NAME)
- (CADAR RESULT))
- (T (LIST '(MEQUAL)
- (CAR VARS)
- (LIST '(MTIMES SIMP)
- (CADAR RESULT)
- (LIST '(MEXPT SIMP)
- DLABEL
- -1.))))))
- (SETQ LABELS (CONS NAME LABELS))
- (SETQ RESULT (CDR RESULT))
- (COND
- ($DISPFLAG (MTELL-OPEN "~M" (NCONC (NCONS '(MLABLE))
- (NCONS NAME)
- (NCONS (EVAL NAME))))))))))
-
- (DEFUN TMERGE (VARS OUTVARS)
- (APPEND OUTVARS
- (PROG (L)
- (MAPCAR #'(LAMBDA (V)
- (COND ((zl-MEMBER V OUTVARS) NIL)
- (T (SETQ L (CONS V L)))))
- VARS)
- (RETURN (REVERSE L)))))
-
- (DEFMFUN $TMLIN (*AA* N M NX)
- (PROG (R VLIST)
- (setq *A2* (*ARRAY nil 'T (f1+ N) (f1+ (f+ M N))))
- (show *a2*)
- (TMRATCONV *AA* N (f+ M N))
- (SETQ
- R
- (CONS
- '(MLIST)
- (MAPCAR
- #'(LAMBDA (RES)
- (CONS '(MLIST)
- (MAPCAR #'(LAMBDA (RESULT)
- (CONS (LIST 'MRAT
- 'SIMP
- VARLIST
- GENVAR)
- RESULT))
- RES)))
- (TMLIN '*A2* N M NX))))
- (*TMREARRAY '*A2*)
- (show *a2*)
- (RETURN R)))
-
- (DEFUN TMKILL (*INDX* K)
- (PROG (NAME SUBINDX J L)
- (COND ((NULL *INDX*) (RETURN NIL)))
- (SETQ NAME (TMACCESS *INDX*))
- (COND ((NOT (NULL (TMEVAL NAME))) (TMSTORE NAME NIL))
- (T (DO ((IND *INDX* (CDR IND)) (COUNT 1. (f1+ COUNT)))
- ((NULL IND))
- (SETQ L (EXTRACT *INDX* COUNT)
- J (CAR L)
- SUBINDX (CADR L))
- (COND ((= J COUNT)
- (TMKILL SUBINDX (f1+ K)))))))))
-
- (DEFUN TMNOMOREUSE (J L K)
- (COND ((AND (= J L) (OR (> K NX) (< K (f1+ IX)))) T) (T NIL)))
-
- (DEFUN TMDEFARRAY (N)
- (PROG (NAME)
- (COND
- (;(GET '*TMARRAYS* 'array)
- (setq *tmarrays* (get-array-pointer *tmarrays*))
- (TMREARRAY (f1- (COND ((CADR (ARRAYDIMS *TMARRAYS*)))
- (T 1.))))))
- (setq *TMARRAYS* (*ARRAY nil 'T (f1+ N)))
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (SETQ NAME (COND ((= I 1.) (make-symbol "M"))
- (T (GENSYM))))
- (COND ((< N (THRESHOLD))
- ;(STORE (aref *TMARRAYS* I) NAME)
- (set name (*ARRAY nil T (f1+ (TMCOMBI N I))))
- (STORE (aref *TMARRAYS* I) (get-array-pointer NAME))
- )
-
- (T (STORE (aref *TMARRAYS* I)
- (LIST NAME
- 'SIMP
- 'array)))))
- (GENSYM "G")))
-
- ;; TMREARRAY kills the TMARRAYS which holds pointers to minors. If (TMARRAYS I)
- ;; is an atom, it is declared array. Otherwise it is hashed array.
-
- (DEFUN TMREARRAY (N)
- (PROG NIL
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (COND ((ATOM (aref *TMARRAYS* I)) (*TMREARRAY (aref *TMARRAYS* I)))
- (T (TM$KILL (CAR (aref *TMARRAYS* I))))))
- (*TMREARRAY '*TMARRAYS*)))
-
- (DEFUN TMACCESS (INDEX)
- (PROG (L)
- (COND ($FOOL (RETURN NIL)))
- (SETQ L (LENGTH INDEX))
- (RETURN
- (COND ((< N (THRESHOLD))
- (LIST 'aref (aref *TMARRAYS* L)
- (DO ((I 1. (f1+ I))
- (X 0. (CAR Y))
- (Y INDEX (CDR Y))
- (SUM 0.))
- ((> I L) (f1+ SUM))
- (DO ((J (f1+ X) (f1+ J)))
- ((= J (CAR Y)))
- (SETQ SUM (f+ SUM
- (TMCOMBI (f- N J)
- (f- L I))))))))
- (T (cons 'aref (CONS (aref *TMARRAYS* L) INDEX)))))) )
-
- (DEFUN TMCOMBI (N I)
- (COND ((> (f- N I) I)
- (// (TMFACTORIAL N (f- N I)) (TMFACTORIAL I 0.)))
- (T (// (TMFACTORIAL N I) (TMFACTORIAL (f- N I) 0.)))))
-
- (DEFUN TMFACTORIAL (I J)
- (COND ((= I J) 1.) (T (f* I (TMFACTORIAL (f1- I) J)))))
-
- (DEFUN TMSTORE (NAME X)
- (COND ((< N (THRESHOLD))
- (EVAL (LIST 'STORE NAME (LIST 'QUOTE X))))
- (T (MSET NAME (LIST '(MQUOTE SIMP) X)) X)))
-
- ;; TMKILLARRAY kills all (N-IX+1)*(N-IX+1) minors which are not necessary for
- ;; the computation of IX-TH variable in the linear equation. Otherwise, they
- ;; will do harm.
-
- (DEFUN TMKILLARRAY (IX)
- (DO ((I (f1+ (f- N IX)) (f1+ I)))
- ((> I N))
- (COND ((< N (THRESHOLD))
- (FILLARRAY (aref *TMARRAYS* I) '(NIL)))
- (T (TM$KILL (CAR (aref *TMARRAYS* I)))))))
-
- (DEFUN TMHEADING NIL NIL)
-
- (DEFUN TMEVAL (E)
- (PROG (RESULT)
- (RETURN (COND ((< N (THRESHOLD)) (EVAL E))
- (T (SETQ RESULT (MEVAL E))
- (COND ((EQUAL RESULT E) NIL)
- (T (CADR RESULT))))))))
-
- (DEFUN TM$KILL (E) (KILL1 E))
-
- (DEFMFUN $TMINVERSE ( *AA*)
- (PROG (R VLIST N M NX)
- (SETQ N (LENGTH (CDR *AA*)) M N NX N)
- (setq *A2* (*ARRAY nil 'T (f1+ N) (f1+ (f+ M N))))
- (TMRATCONV *AA* N N)
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (DO ((J 1. (f1+ J)))
- ((> J M))
- (STORE (aref *A2* I (f+ N J))
- (COND ((= I J) '(1. . 1.))
- (T '(0. . 1.))))))
- (SETQ
- R
- (MAPCAR
- #'(LAMBDA (RES)
- (CONS
- '(MLIST)
- (MAPCAR
- #'(LAMBDA (RESULT)
- ($RATDISREP (CONS (LIST 'MRAT
- 'SIMP
- VARLIST
- GENVAR)
- RESULT)))
- RES)))
- (TMLIN '*A2* N M NX)))
- (SETQ R
- (LIST '(MTIMES SIMP)
- (LIST '(MEXPT SIMP) (CADAR R) -1.)
- (CONS '($MATRIX SIMP) (CDR R))))
- (*TMREARRAY '*A2*)
- (RETURN R)))
-
- (DEFUN *TMREARRAY (X) (*REARRAY X))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;THIS IS A UTILITY PACKAGE FOR SPARSE
- ;;MATRIX INVERSION. A3 IS A N*N MATRIX.
- ;;IT RETURNS A LIST OF LISTS, SUCH AS
- ;;((I1 I2 ...) (J1 J2...) ...) WHERE (I1
- ;;I2 ..) SHOWS THE ROWS WHICH BELONGS TO
- ;;THE FIRST BLOCK, AND SO ON. THE ROWS
- ;;SHOUD BE REORDERED IN THIS ORDER. THE
- ;;COLUMNS ARE NOT CHANGED. IT RETURNS NIL
- ;;IF A3 IS "OBVIOUSLY" SINGULAR.
-
- ;; (DEFUN TMISOLATE (A3 N)
- ;; (PROG (NODELIST)
- ;; (SETQ A3 (GET A3 'ARRAY))
- ;; (setq B (*ARRAY nil 'T (f1+ N) (f1+ N)))
- ;; (setq ROW (*ARRAY nil 'T (f1+ N)))
- ;; (setq COL (*ARRAY nil 'T (f1+ N)))
- ;; (DO ((I 1. (f1+ I)))
- ;; ((> I N))
- ;; (STORE (ROW I) I)
- ;; (STORE (COL I) I))
- ;; (DO ((I 1. (f1+ I)))
- ;; ((> I N))
- ;; (DO ((J 1. (f1+ J)))
- ;; ((> J N))
- ;; (STORE (B I J)
- ;; (NOT (EQUAL (AREF A3 I J)
- ;; '(0. . 1.))))))
- ;; (COND ((NULL (TMPIVOT-ISOLATE 1.))
- ;; (SETQ NODELIST NIL)
- ;; (GO EXIT)))
- ;; (DO ((I 1. (f1+ I)))
- ;; ((> I N))
- ;; (DO ((J 1. (f1+ J)))
- ;; ((> J I))
- ;; (STORE (B (ROW J) (COL I))
- ;; (OR (B (ROW I) (COL J))
- ;; (B (ROW J) (COL I))))
- ;; (STORE (B (ROW I) (COL J)) (B (ROW J) (COL I))))
- ;; (STORE (B (ROW I) (COL I)) T))
- ;; (DO ((I 1. (f1+ I)))
- ;; ((> I N))
- ;; (COND ((EQ (B (ROW I) (COL I)) T)
- ;; (SETQ NODELIST
- ;; (CONS (TMPULL-OVER I N) NODELIST)))))
- ;; EXIT
- ;; (*TMREARRAY 'B)
- ;; (*TMREARRAY 'ROW)
- ;; (*TMREARRAY 'COL)
- ;; (RETURN (REVERSE NODELIST)))))
-
- ;; (DEFUN TMPULL-OVER (P N)
- ;; (PROG (Q)
- ;; (STORE (B (ROW P) (COL P)) NIL)
- ;; (DO ((J 1. (f1+ J)))
- ;; ((> J N) (SETQ Q NIL))
- ;; (COND ((EQ (B (ROW P) (COL J)) T)
- ;; (RETURN (SETQ Q J)))))
- ;; (COND ((NULL Q) (RETURN (LIST (ROW P))))
- ;; (T (DO ((J 1. (f1+ J)))
- ;; ((> J N))
- ;; (STORE (B (ROW Q) (COL J))
- ;; (OR (B (ROW Q) (COL J))
- ;; (B (ROW P) (COL J))))
- ;; (STORE (B (ROW J) (COL Q))
- ;; (B (ROW Q) (COL J))))
- ;; (TMCRIP P)
- ;; (RETURN (CONS (ROW P) (TMPULL-OVER Q N)))))))
-
- ;; (DEFUN TMCRIP (P)
- ;; (DO ((I 1. (f1+ I)))
- ;; ((> I N))
- ;; (STORE (B (ROW P) (COL I)) NIL)
- ;; (STORE (B (ROW I) (COL P)) NIL)))
-
- ;;TMPIVOT-ISOLATE CARRIES OUT PIVOTTING
- ;;SO THAT THE ALL DIAGONAL ELEMENTS ARE
- ;;NONZERO. THIS GARANTIES WE HAVE MAXIMUM
- ;;NUMBER OF BLOCKS ISOLATED.
-
- (DEFUN TMPIVOT-ISOLATE (K)
- (COND ((> K N) T)
- (T (DO ((I K (f1+ I)))
- ((> I N) NIL)
- (COND ((aref *B* (aref *ROW* I) (aref *COL* K))
- (TMEXCHANGE '*ROW* K I)
- (COND ((TMPIVOT-ISOLATE (f1+ K)) (RETURN T))
- (T (TMEXCHANGE '*ROW*
- K
- I)))))))))
-
- (DEFUN TMEXCHANGE (ROWCOL I J)
- (PROG (DUMMY)
- (SETQ ROWCOL (get-array-pointer rowcol))
- (SETQ DUMMY (AREF ROWCOL I))
- (STORE (AREF ROWCOL I) (AREF ROWCOL J))
- (STORE (AREF ROWCOL J) DUMMY)))
-
-
- ;; PROGRAM TO PREDICT ZERO ELEMENTS IN
- ;; THE SOLUTION OF INVERSE OR LINEAR
- ;; EQUATION. A IS THE COEFFICIENT MATRIX.
- ;; B IS THE RIGHT HAND SIDE MATRIX FOR
- ;; LINEAR EQUATIONS. A3 IS N*N AND B IS
- ;; M*M. X IS AN N*M MATRIX WHERE T -NIL
- ;; PATTERN SHOWING THE ZERO ELEMENTS IN
- ;; THE RESULT IS RETURND. T CORRESPONDS TO
- ;; NON-ZERO ELEMENT. IN THE CASE OF
- ;; INVERSE, YOU CAN PUT ANYTHING (SAY,NIL)
- ;; FOR B AND 0 FOR M. NORMALLY IT RETURNS
- ;; T, BUT IN CASE OF SINGULAR MATRIX, IT
- ;; RETURNS NIL.
-
- ;; (DEFUN TMPREDICT (A3 B X N M)
- ;; (PROG (FLAGINV FLAG-NONSINGULAR)
- ;; (SETQ A3 (GET A3 'ARRAY) B (GET B 'ARRAY) X (GET X 'ARRAY))
- ;; (setq AA (*ARRAY nil 'T (f1+ N) (f1+ N)))
- ;; (setq ROW (*ARRAY nil 'T (f1+ N)))
- ;; (SETQ FLAGINV (= M 0.))
- ;; (COND (FLAGINV (SETQ M N)))
- ;; (DO ((I 1. (f1+ I)))
- ;; ((> I N))
- ;; (DO ((J 1. (f1+ J)))
- ;; ((> J N))
- ;; (STORE (AA I J)
- ;; (NOT (EQUAL (AREF A3 I J) '(0. . 1.))))))
- ;; (DO ((I 1. (f1+ I)))
- ;; ((> I N))
- ;; (DO ((J 1. (f1+ J)))
- ;; ((> J M))
- ;; (STORE (AREF X I J)
- ;; (COND (FLAGINV (EQ I J))
- ;; (T (EQUAL (AREF B I J)
- ;; '(0. . 1.)))))))
- ;; (DO ((I 1. (f1+ I))) ((> I N)) (STORE (ROW I) I))
- ;; ;FORWARD ELIMINATION.
- ;; (DO ((I 1. (f1+ I)))
- ;; ((> I N))
- ;; (SETQ FLAG-NONSINGULAR
- ;; (DO ((II I (f1+ II)))
- ;; ((> II N) NIL)
- ;; (COND ((AA (ROW II) I)
- ;; (TMEXCHANGE 'ROW II I)
- ;; (RETURN T)))))
- ;; (COND ((NULL FLAG-NONSINGULAR) (RETURN NIL)))
- ;; (DO ((II (f1+ I) (f1+ II)))
- ;; ((> II N))
- ;; (COND ((AA (ROW II) I)
- ;; (DO ((JJ (f1+ I) (f1+ JJ)))
- ;; ((> JJ N))
- ;; (STORE (AA (ROW II) JJ)
- ;; (OR (AA (ROW I) JJ)
- ;; (AA (ROW II) JJ))))
- ;; (DO ((JJ 1. (f1+ JJ)))
- ;; ((> JJ M))
- ;; (STORE (AREF X (ROW II) JJ)
- ;; (OR (AREF X (ROW I) JJ)
- ;; (AREF X (ROW II) JJ))))))))
- ;; (COND ((NULL FLAG-NONSINGULAR) (GO EXIT))) ;GET OUT BACKWARD SUBSTITUTION
- ;; (DO ((I (f1- N) (f1- I)))
- ;; ((< I 1.))
- ;; (DO ((L 1. (f1+ L)))
- ;; ((> L M))
- ;; (STORE (AREF X (ROW I) L)
- ;; (OR (AREF X (ROW I) L)
- ;; (DO ((J (f1+ I) (f1+ J)) (SUM))
- ;; ((> J N) SUM)
- ;; (SETQ SUM
- ;; (OR SUM
- ;; (AND (AA (ROW I) J)
- ;; (AREF
- ;; X
- ;; (ROW J)
- ;; L)))))))))
- ;; ;RECOVER THE ORDER.
- ;; (TMPERMUTE 'X N M 0. 0. 'ROW N 'ROW)
- ;; EXIT (*TMREARRAY 'ROW) (*TMREARRAY 'AA) (RETURN FLAG-NONSINGULAR)))
-
- ;TMPERMUTE PERMUTES THE ROWS OR COLUMNS
- ;OF THE N*M MATRIX AX ACCORDING TO THE
- ;SPECIFICATION OF INDEXLIST. THE FLAG
- ;MUST BE SET 'ROW IF ROW PERMUTATION IS
- ;DESIRED , OR 'COL OTHERWISE. THE RESULT
- ;IS IN AX. NM IS THE DIMENSION OF
- ;INDEXLIST.
-
- (DEFUN TMPERMUTE (AX N M RBIAS CBIAS INDEXLIST NM FLAG)
- (PROG (K L)
- ; (SETQ AX (GET AX 'array)
- ; INDEXLIST (GET INDEXLIST 'array))
- (setq ax (get-array-pointer ax))
- (setq indexlist (get-array-pointer indexlist))
- (ARRAY *INDX* T (f1+ NM))
- (DO ((I 1. (f1+ I)))
- ((> I NM))
- (STORE (aref *INDX* I) (AREF INDEXLIST I)))
- (DO ((I 1. (f1+ I)))
- ((> I NM))
- (COND ((NOT (= (aref *INDX* I) I))
- (PROG NIL
- (TMMOVE AX N M RBIAS CBIAS I 0. FLAG)
- (SETQ L I)
- LOOP (SETQ K (aref *INDX* L))
- (STORE (aref *INDX* L) L)
- (COND ((= K I)
- (TMMOVE AX
- N
- M
- RBIAS
- CBIAS
- 0.
- L
- FLAG))
- (T (TMMOVE AX
- N
- M
- RBIAS
- CBIAS
- K
- L
- FLAG)
- (SETQ L K)
- (GO LOOP)))))))
- (*TMREARRAY '*INDX*)))
-
- (DEFUN TMMOVE (AX N M RBIAS CBIAS I J FLAG)
- (PROG (LL)
- (setq ax (get-array-pointer ax))
- (SETQ LL (COND ((EQ FLAG '*ROW*) (f- M CBIAS))
- (T (f- N RBIAS))))
- (DO ((K 1. (f1+ K)))
- ((> K LL))
- (COND ((EQ FLAG '*ROW*)
- (STORE (AREF
- AX
- (f+ RBIAS J)
- (f+ CBIAS K))
- (AREF
- AX
- (f+ RBIAS I)
- (f+ CBIAS K))))
- (T (STORE (AREF
- AX
- (f+ RBIAS K)
- (f+ CBIAS J))
- (AREF
- AX
- (f+ RBIAS K)
- (f+ CBIAS I))))))))
-
- ;TMSYMETRICP CHECKS THE SYMETRY OF THE MATRIX.
-
- (DEFUN TMSYMETRICP (A3 N)
- (SETQ A3 (GET-array-pointer A3))
- (DO ((I 1. (f1+ I)))
- ((> I N) T)
- (COND ((NULL (DO ((J (f1+ I) (f1+ J)))
- ((> J N) T)
- (COND ((NOT (EQUAL (AREF
- A3
- I
- J)
- (AREF
- A3
- J
- I)))
- (RETURN NIL)))))
- (RETURN NIL)))))
-
- ;TMLATTICE CHECKS THE "LATTICE"
- ;STRUCTURE OF THE MATRIX A. IT RETURNS
- ;NIL IF THE MATRIX IS "OBVIOUSLY"
- ;SINGULAR. OTHERWISE IT RETURNS A LIST
- ;(L1 L2 ... LM) WHERE M IS THE NUMBER OF
- ;BLOCKS (STRONGLY CONNECTED SUBGRAPHS),
- ;AND L1 L2 ... ARE LIST OF ROW AND
- ;COLUMN NUBERS WHICH BELONG TO EACH
- ;BLOCKS. THE LIST LOOKS LIKE ((R1 C1)
- ;(R2 C2) ...) WHERE R R'S ARE ROWS AND
- ;C'S ARE COLUMMS.
-
- (DEFUN TMLATTICE (A3 XROW XCOL N)
- (PROG (RES)
- (setq a3 (get-array-pointer a3))
- (setq xrow (get-array-pointer xrow))
- (setq xcol (get-array-pointer xcol))
- (setq *b* (*ARRAY nil T (f1+ N) (f1+ N)))
- (setq *ROW* (*ARRAY nil T (f1+ N)))
- (setq *col* (*ARRAY nil T (f1+ N)))
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (DO ((J 1. (f1+ J)))
- ((> J N))
- (STORE (aref *B* I J)
- (NOT (EQUAL (AREF A3 I J)
- '(0. . 1.))))))
- (DO ((I 0. (f1+ I)))
- ((> I N))
- (STORE (aref *ROW* I) I)
- (STORE (aref *COL* I) I))
- (COND ((NULL (TMPIVOT-ISOLATE 1.))
- (SETQ RES NIL)
- (GO EXIT)))
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (STORE (aref *B* (aref *ROW* I) (aref *COL* I)) I)
- (STORE (aref *B* (aref *ROW* I) (aref *COL* 0.)) T
- ))
- (TMLATTICE1 1.)
- (SETQ RES (TMSORT-LATTICE XROW XCOL))
- EXIT (*TMREARRAY '*B*)
- (*TMREARRAY '*ROW*)
- (*TMREARRAY '*COL*)
- (RETURN RES)))
-
- (DEFUN TMLATTICE1 (K)
- (COND ((= K N) NIL)
- (T (TMLATTICE1 (f1+ K))
- (DO ((LOOPPATH))
- (NIL)
- (COND ((SETQ LOOPPATH (TMPATHP K K))
- (TMUNIFY-LOOP K (CDR LOOPPATH)))
- (T (RETURN NIL)))))))
-
- (DEFUN TMPATHP (J K)
- (COND ((EQUAL (aref *B* (aref *ROW* J) (aref *COL* K)) T) (LIST J K))
- (T (DO ((JJ K (f1+ JJ)) (PATH))
- ((> JJ N))
- (COND ((AND (EQUAL (aref *B* (aref *ROW* J) (aref *COL* JJ)) T)
- (SETQ PATH (TMPATHP JJ K)))
- (RETURN (CONS J PATH))))))))
-
- (DEFUN TMUNIFY-LOOP (K CHAIN)
- (PROG (L DUMMYK DUMMYL)
- (SETQ L (CAR CHAIN))
- (COND ((= L K) (RETURN NIL)))
- (SETQ DUMMYK (aref *B* (aref *ROW* K) (aref *COL* K)))
- (SETQ DUMMYL (aref *B* (aref *ROW* L) (aref *COL* L)))
- (STORE (aref *B* (aref *ROW* K) (aref *COL* K)) NIL)
- (STORE (aref *B* (aref *ROW* L) (aref *COL* L)) NIL)
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (STORE (aref *B* (aref *ROW* K) (aref *COL* I))
- (OR (aref *B* (aref *ROW* K) (aref *COL* I)) (aref *B* (aref *ROW* L) (aref *COL* I))))
- (STORE (aref *B* (aref *ROW* I) (aref *COL* K))
- (OR (aref *B* (aref *ROW* I) (aref *COL* K)) (aref *B* (aref *ROW* I) (aref *COL* L))))
- (STORE (aref *B* (aref *ROW* L) (aref *COL* I)) NIL)
- (STORE (aref *B* (aref *ROW* I) (aref *COL* L)) NIL))
- (STORE (aref *B* (aref *ROW* K) (aref *COL* K)) DUMMYL)
- (STORE (aref *B* (aref *ROW* L) (aref *COL* L)) DUMMYK)
- (STORE (aref *B* (aref *ROW* K) (aref *COL* 0.)) T)
- (STORE (aref *B* (aref *ROW* L) (aref *COL* 0.)) NIL)
- (TMUNIFY-LOOP K (CDR CHAIN))))
-
- (DEFUN TMSORT-LATTICE (XROW XCOL)
- (PROG (NODELIST RESULT)
- (SETQ NODELIST (TMSORT1))
- (SETQ
- RESULT
- (DO ((X NODELIST (CDR X)) (RESULT))
- ((NULL X) RESULT)
- (SETQ RESULT
- (CONS (DO ((NEXT (aref *B* (aref *ROW* (CAR X))
- (aref *COL* (CAR X)))
- (aref *B* (aref *ROW* NEXT) (aref *COL* NEXT)))
- (RES))
- ((= NEXT (CAR X))
- (CONS (LIST (aref *ROW* NEXT) (aref *COL* NEXT))
- RES))
- (SETQ RES
- (CONS (LIST (aref *ROW* NEXT)
- (aref *COL* NEXT))
- RES)))
- RESULT))))
- (DO ((LIST1 RESULT (CDR LIST1)) (I 1.))
- ((NULL LIST1))
- (DO ((LIST2 (CAR LIST1) (CDR LIST2)))
- ((NULL LIST2))
- (STORE (AREF XROW I) (CAAR LIST2))
- (STORE (AREF XCOL I) (CADAR LIST2))
- (SETQ I (f1+ I))))
- (RETURN RESULT)))
-
- ;; (DEFUN TMLESS (I J) (B (ROW I) (COL J)))
-
- (DEFUN TMSORT1 NIL
- (DO ((I 1. (f1+ I)) (RESULT))
- ((> I N) RESULT)
- (COND ((AND (aref *B* (aref *ROW* I) (aref *COL* 0.)) (TMMAXP I))
- (DO ((J 1. (f1+ J)))
- ((> J N))
- (COND ((NOT (= J I))
- (STORE (aref *B* (aref *ROW* I) (aref *COL* J)) NIL))))
- (STORE (aref *B* (aref *ROW* I) (aref *COL* 0.)) NIL)
- (SETQ RESULT (CONS I RESULT))
- (SETQ I 0.)))))
-
- (DEFUN TMMAXP (I)
- (DO ((J 1. (f1+ J)))
- ((> J N) T)
- (COND ((AND (NOT (= I J)) (aref *B* (aref *ROW* J) (aref *COL* I)))
- (RETURN NIL)))))
-
- ;;UNPIVOT IS USED IN PAUL WANG'S PROGRAM
- ;;TO RECOVER THE PIVOTTING. TO GET THE
- ;;INVERSE OF A, PAUL'S PROGRAM COMPUTES
- ;;THE INVERSE OF U*A*V BECAUSE OF
- ;;BLOCKING. LET THE INVERSE Y. THEN
- ;;A^^-1=V*Y*U. WHERE U AND V ARE
- ;;FUNDAMENTAL TRANSFORMATION
- ;;(PERMUTATION). UNPIVOT DOES THIS,
- ;;NAMELY, GIVEN A MATRIX A3, INDEX ROW
- ;;AND COL ,WHICH CORRESPONDS TO THE Y , U
- ;; AND V, RESPECTIVELY, IT COMPUTES V*Y*U
- ;;AND RETURNS IT TO THE SAME ARGUMENT A.
-
- (DEFUN TMUNPIVOT (A3 *ROW* *COL* N M)
- (PROG NIL
- (setq *col* (get-array-pointer *col*))
- (setq *row* (get-array-pointer *row*))
- (setq *rowinv* (*ARRAY nil T (f1+ N)))
- (setq *colinv* (*ARRAY nil T (f1+ N)))
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (STORE (aref *ROWINV* (AREF *ROW* I)) I))
- (DO ((I 1. (f1+ I)))
- ((> I N))
- (STORE (aref *COLINV* (AREF *COL* I)) I))
- (TMPERMUTE A3 N M 0. N '*COLINV* N '*ROW*)
- (TMPERMUTE A3 N M 0. N '*ROWINV* N '*COL*)
- (*TMREARRAY '*ROWINV*)
- (*TMREARRAY '*COLINV*)))
-
- #-NIL
- (DECLARE-TOP(UNSPECIAL N #-cl vlist NX IX))
-